﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using CommonWFLibrary;
using IndicoInterface.SimpleAgendaDataModel;
using DTBuilderLib;
using System.IO;

namespace DeepTalkWF
{
    /// <summary>
    /// Given the proper meeting info, download all the talks for it!
    /// </summary>
	public partial class DownloadTalks: LongRunningActivityBase
	{
        /// <summary>
        /// Get or set the normalized meeting agenda. Used as input for this activity.
        /// </summary>
        public Meeting MeetingInfo
        {
            get { return (Meeting)GetValue(MeetingInfoProperty); }
            set { SetValue(MeetingInfoProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MeetingInfo.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MeetingInfoProperty =
            DependencyProperty.Register("MeetingInfo", typeof(Meeting), typeof(DownloadTalks), new PropertyMetadata(null));

        /// <summary>
        /// The temp directory where we should download everything. It must have enough room
        /// so that we can store everythign there.
        /// </summary>
        public DirectoryInfo TempDirectory
        {
            get { return (DirectoryInfo)GetValue(TempDirectoryProperty); }
            set { SetValue(TempDirectoryProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TempDirectory.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TempDirectoryProperty =
            DependencyProperty.Register("TempDirectory", typeof(DirectoryInfo), typeof(DownloadTalks), new PropertyMetadata(null));

        /// <summary>
        /// The resulting meeting info -- updated with the locations of the PDF/PPT's.
        /// </summary>
        public Meeting DownloadedMeetingInfo
        {
            get { return (Meeting)GetValue(DownloadedMeetingInfoProperty); }
            set { SetValue(DownloadedMeetingInfoProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DownloadedMeetingInfo.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DownloadedMeetingInfoProperty =
            DependencyProperty.Register("DownloadedMeetingInfo", typeof(Meeting), typeof(DownloadTalks), new PropertyMetadata(null));


        /// <summary>
        /// Build activity that will download a meeting agenda.
        /// </summary>
		public DownloadTalks()
		{
			InitializeComponent();
            TimesToRetry = 10; // Keep trying by default if we crash!
		}

        [Serializable]
        public class Args
        {
            public string _tempDirectory;
            public Meeting _agendaData;
        }

        [LongRunningGatherArguments]
        public Args Gather ()
        {
            Args a = new Args();
            a._agendaData = MeetingInfo;
            a._tempDirectory = TempDirectory.FullName;

            return a;
        }

        [Serializable]
        public class Results
        {
            public Meeting _result;
        }

        /// <summary>
        /// Put everything back into our properties.
        /// </summary>
        /// <param name="r"></param>
        [LongRunningDistributeArguments]
        public void Distribute(Results r)
        {
            DownloadedMeetingInfo = r._result;
        }

        /// <summary>
        /// Start the spawned off thread going.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="c"></param>
        [LongRunningMethodStarter]
        static public void Run(LongRunningContext context, Args c)
        {
            JobDownloader jd = new JobDownloader();
            jd.FileDownloadLocation = c._tempDirectory;
            jd.StartMeetingDownload(c._agendaData,
                null,
                m => ReportDLDone(context, m));
        }

        /// <summary>
        /// Ok -- we are done with the download. We should not report our information back
        /// to the user.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        private static void ReportDLDone(LongRunningContext context, Meeting m)
        {
            Results r = new Results();
            r._result = m;
            context.Complete(r);
        }
	}
}
